An ever-increasing number of e-commerce providers or e-businesses rely on application server technology as the lifeblood of their business. Application servers form a proven foundation for developing and supporting e-commerce applications, providing the presentation, business and information-access logic, security and management services, and the underlying infrastructure required for running highly scalable and mission-critical software applications. Increasingly, the demands of today's modern businesses require support for a new breed of Web and wireless applications, helping to meet the needs of increasingly sophisticated customers.
One such application server, WebLogic Server, from BEA Systems, Inc. San Jose, Calif., is based on an implementation of the Java 2 Enterprise Edition (J2EE) specification. WebLogic Server is used as the backbone for many of today's most sophisticated e-business applications, and plays an integral role in a tightly integrated, comprehensive infrastructure that delivers commerce, personalization, campaign management, enterprise integration, workflow management, and business-to-business collaboration. WebLogic Server manages all of the underlying complexities of a business' e-commerce applications, allows the organization to focus instead on delivering new and innovative products and services.
A typical application server, including WebLogic Server, supports a variety of clients, including Web browsers, standalone clients, and wireless devices. On the server side, WebLogic Server operates on a variety of operating systems. On the back-end, WebLogic Server integrates with relational databases, messages queues, and legacy systems. WebLogic Server also provides support for features such as Servlets, Java Server Pages (JSPs), Enterprise JavaBeans (EJBs), and Java Messaging Service (JMS), to provide access to standard network protocols, database, and messaging systems. Clients can communicate with these server-side features using, for example, Remote Method Invocation (RMI) calls. RMI allows an object running on a first Java virtual machine or JVM to invoke methods on a remote object running on a second JVM. Typically the machine making the invoke is referred to as the client, and the machine responding to the invoke referred to as the server.
A problem with many application servers as they are currently implemented, is that the server must keep track of all of the remote objects as they are created. As the server handles request from clients, additional object implementations may be created. Because in many instances the server does not know when (if ever) these object implementations will be reused by the client, it may not delete them for a long period of time. As a result, the number of objects steadily increases during use, and remain on the server for indefinite periods of time. There is a lot of system overhead associated with these objects—for example, each object has to be runtime setup to take client calls. The increase in objects thus limits the overall scalability of the server, and as such they should be garbage collected when no longer in use. Mechanisms that can increase both server scalability, and flexibility in handling and managing a large number of object instances are highly desirable.
One approach to this problem is through lazy activation of RMI objects, as described in the Java RMI Specification, incorporated herein by reference. Object activation can be used to provide persistent references to objects, and to manage the execution of object implementations. In RMI lazy activation, when an activatable object is accessed through a remote method invocation the system initiates the Object's execution inside an appropriate JVM. As referred to in the context of RMI lazy activation, an active object is a remote object that is instantiated and exported in a JVM. A passive object is one that is not yet instantiated) in a JVM, but which can be brought into an active state. Activation transforms a passive object into an active object, a process that requires the object be associated with a JVM. Lazy activation essentially defers activating an object until a client's first use (usually when the client invokes the object).
In RMI lazy activation, activation of remote objects is implemented using a process known as faulting remote reference—a reference to a remote object that “faults in” the active objects reference upon the first method invocation to the object. In practice, the remote objects stub contains the faulting remote reference. Each faulting reference maintains both a persistent reference (activation identifier, or activation id), and a transient remote reference to the target remote object. The remote object's activation ID contains the necessary information to allow a third party to activate the object. The transient reference is then used to actually contact the executing object. If the live reference to a remote object is null, the target object is not known to be active. When invoked, the faulting reference obtains a “live” reference, or remote reference for the newly-activated object. The faulting reference then forwards method invocations to the underlying remote reference, which in turn forwards the method invocation to the remote object.
During a remote method invocation, if the live reference for a target object is unknown, the faulting reference engages in the activation protocol. An activator supervises the activation, usually by mapping activation identifiers to the information necessary to activate an object, such as the object's class; and by starting up JVMs (when necessary) and forwarding requests for object activation to the correct activation group inside the remote JVM. Activation groups receive the request to activate an object in the JVM, and return the activated object back to the activator. During activation a faulting reference provides an activation ID and calls the activator to activate the object associated with the identifier. The activator looks up the object's activation descriptor to find the JVM in which it is activated, the object's class name, and object-specific initialization data in marshalled form. The activator then forwards the activation request to the specified group. If the activation group does not already exist, the activator initiates an activation group and then forwards the activation request to the newly executed group. The activation group loads the class for the object and instantiates the object. When the object is activated, the activation group passes back a marshalled object reference to the activator. The activation ID and active reference pairing is recorded, and the active reference returned to the faulting reference. The faulting reference then forwards method invocations via the live reference directly to the remote object.